/**
 * @file        ring_buffer.c
 * @brief       环形缓冲区模块实现文件
 * @note        实现高效的环形缓冲区数据结构，支持覆盖模式，适用于嵌入式系统数据缓存
 * @author      靳普诏(puzhao.jin@hopechart.com)
 * @date        2025/06/03
 * @version     1.0

 * @par         修改日志
 * <table>
 * <tr><th>Date         <th>Version     <th>Author      <th> Description
 * <tr><td>2025/06/03   <td>1.0         <td>靳普诏       <td> 创建初始版本
 * @copyright 杭州鸿泉物联网技术股份有限公司
 */
 
#include "az_clib/ds/ring_buffer.h"

/**
 * @brief 创建并初始化环形缓冲区
 */
Int32 TRingBufferCreate(TRingBuffer *self, UInt8 *buffer, UInt32 buffer_size, Bool allow_overwrite)
{
    // 参数校验
    if (self == NULL || buffer == NULL) {
        return -1;
    }
    if (buffer_size == 0) {
        return -2;
    }
    
    // 初始化结构体
    self->buffer_start = buffer;
    self->buffer_end = buffer_size;
    self->write_pos = buffer;
    self->read_pos = buffer;
    self->allow_overwrite = allow_overwrite;
    self->flag_created = 1;
    
    return 0;
}

/**
 * @brief 销毁环形缓冲区
 */
void TRingBufferDestroy(TRingBuffer *self)
{
    if (self == NULL) {
        return;
    }
    
    // 清理控制结构
    self->buffer_start = NULL;
    self->buffer_end = 0;
    self->write_pos = NULL;
    self->read_pos = NULL;
    self->allow_overwrite = False;
    self->flag_created = 0;
}

/**
 * @brief 向环形缓冲区写入数据
 */
Int32 TRingBufferWrite(TRingBuffer *self, const void *data, UInt32 data_size)
{
    if (self == NULL || data == NULL) {
        return -1;
    }
    if (self->flag_created != 1) {
        return -2;
    }
    if (data_size == 0) {
        return 0;
    }
    
    const UInt8 *src = (const UInt8 *)data;
    UInt32 bytes_written = 0;
    
    // 在不允许覆盖模式下，获取可用空间
    if (!self->allow_overwrite) {
        Int32 free_space = TRingBufferGetFreeSize(self);
        if (free_space <= 0) {
            return 0;  // 没有可用空间
        }
        if (data_size > (UInt32)free_space) {
            data_size = (UInt32)free_space;
        }
    }
    
    // 写入数据
    for (UInt32 i = 0; i < data_size; i++) {
        *self->write_pos = src[i];
        self->write_pos++;
        bytes_written++;
        
        // 处理指针回绕
        if (self->write_pos >= self->buffer_start + self->buffer_end) {
            self->write_pos = self->buffer_start;
        }
        
        // 在允许覆盖模式下，如果写指针赶上读指针，需要移动读指针
        if (self->allow_overwrite && self->write_pos == self->read_pos) {
            self->read_pos++;
            if (self->read_pos >= self->buffer_start + self->buffer_end) {
                self->read_pos = self->buffer_start;
            }
        }
    }
    
    return bytes_written;
}

/**
 * @brief 从环形缓冲区读取数据
 */
Int32 TRingBufferRead(TRingBuffer *self, void *data, UInt32 data_size)
{
    if (self == NULL || data == NULL) {
        return -1;
    }
    if (self->flag_created != 1) {
        return -2;
    }
    if (data_size == 0) {
        return 0;
    }
    
    UInt8 *dest = (UInt8 *)data;
    UInt32 bytes_read = 0;
    Int32 used_size = TRingBufferGetUsedSize(self);
    
    if (used_size <= 0) {
        return 0;  // 没有数据可读
    }
    
    UInt32 bytes_to_read = (data_size > (UInt32)used_size) ? (UInt32)used_size : data_size;
    
    // 读取数据
    for (UInt32 i = 0; i < bytes_to_read; i++) {
        dest[i] = *self->read_pos;
        self->read_pos++;
        bytes_read++;
        
        // 处理指针回绕
        if (self->read_pos >= self->buffer_start + self->buffer_end) {
            self->read_pos = self->buffer_start;
        }
    }
    
    return bytes_read;
}

/**
 * @brief 获取环形缓冲区已使用空间大小
 */
Int32 TRingBufferGetUsedSize(TRingBuffer *self)
{
    if (self == NULL) {
        return -1;
    }
    if (self->flag_created != 1) {
        return -2;
    }
    
    if (self->write_pos >= self->read_pos) {
        return (Int32)(self->write_pos - self->read_pos);
    } else {
        return (Int32)(self->buffer_end - (self->read_pos - self->write_pos));
    }
}

/**
 * @brief 获取环形缓冲区剩余可用空间大小
 */
Int32 TRingBufferGetFreeSize(TRingBuffer *self)
{
    if (self == NULL) {
        return -1;
    }
    if (self->flag_created != 1) {
        return -2;
    }
    
    Int32 used_size = TRingBufferGetUsedSize(self);
    if (used_size < 0) {
        return used_size;  // 返回错误码
    }
    
    // 预疙1字节区分空满状态
    return (Int32)(self->buffer_end - used_size - 1);
}

/**
 * @brief 获取环形缓冲区总容量
 */
Int32 TRingBufferGetBufferSize(TRingBuffer *self)
{
    if (self == NULL) {
        return -1;
    }
    if (self->flag_created != 1) {
        return -2;
    }
    
    return (Int32)self->buffer_end;
}

/**
 * @brief 清空环形缓冲区
 */
void TRingBufferClear(TRingBuffer *self)
{
    if (self == NULL || self->flag_created != 1) {
        return;
    }
    
    // 重置读写指针到起始位置
    self->write_pos = self->buffer_start;
    self->read_pos = self->buffer_start;
}

